home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’97 / Brought to you by... / Source-n-stuff / Offscreen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-28  |  7.1 KB  |  248 lines  |  [TEXT/CWIE]

  1. #include "Offscreen.h"
  2.  
  3. #define __EqualRect(r1,r2) \
  4.         ( (*(long *)&(r1).top == *(long *)&(r2).top) && \
  5.             (*(long *)&(r1).bottom == *(long *)&(r2).bottom) )
  6.  
  7. // ---------------------------------------------------------------------------
  8. //        • StOffscreenGWorld
  9. // ---------------------------------------------------------------------------
  10. //    Constructor
  11. //
  12. //    Upon entry, the current port must to set to where you want to copy
  13. //    the offscreen image when the StOffscreenGWorld object is destroyed
  14. //
  15. //    The inPixelDepth, inFlags, inCTableH, and inGDeviceH parameters
  16. //    all have default values (see the header file), so you don't need
  17. //    to specify them.
  18. //
  19. //    However, in some cases, you may want to specify an absolute
  20. //    pixel depth. It may also be useful to set the useTempMem flag
  21. //    so that the offscreen pixels are allocated in temporary memory.
  22. //    This is appropriate because StOffscreenGWorlds are meant to be
  23. //    temporary, stack-based, objects.
  24.  
  25. WindowOffscreen *DrawOffscreen( const Rect *inBounds, WindowPtr theWindow)
  26. {
  27. #if powerc
  28.     short inPixelDepth = 0;
  29.     GWorldFlags inFlags = useTempMem;
  30.     CTabHandle inCTableH = nil;
  31.     GDHandle inGDeviceH = nil;
  32.     WindowOffscreen    *theOffscreen;
  33.     Rect    bRect = (inBounds ? *inBounds : theWindow->portRect);
  34.     Rect    gwRect =  bRect;
  35.     
  36.     QDErr    err;
  37.     
  38.     
  39.     SetPort(theWindow);
  40.  
  41.     if ((theOffscreen = (WindowOffscreen *) NewPtr(sizeof(WindowOffscreen))) == 0L)
  42.         return(0L);
  43.         // We need to save the current GWorld because the image from
  44.         // the offscreen GWorld will be copied into this GWorld
  45.         // in the Destructor.
  46.         
  47.     GetGWorld(&theOffscreen->mSavePort, &theOffscreen->mSaveDevice);
  48.     
  49.     theOffscreen->mBounds =  bRect;
  50.  
  51.     theOffscreen->mMacGWorld = nil;
  52.     
  53.         // NewGWorld interprets the bounds in global coordinates
  54.         // when specifying a zero pixel depth. It uses the maximum
  55.         // depth of all screen devices intersected by the bounds.
  56.     
  57.     if (inPixelDepth == 0) {
  58.         LocalToGlobal(&topLeft(gwRect));
  59.         LocalToGlobal(&botRight(gwRect));
  60.     }
  61.  
  62.     err = NewGWorld(&theOffscreen->mMacGWorld, inPixelDepth, &gwRect,
  63.                             inCTableH, inGDeviceH, inFlags);
  64.  
  65.     if(err || theOffscreen->mMacGWorld == nil) {
  66.         DisposePtr((Ptr)theOffscreen);
  67.         return(0L);    
  68.     }        
  69.  
  70.         // Make offscreen GWorld the current one and prepare it
  71.         // for drawing by setting the coordinate system, and locking
  72.         // and erasing the pixels.
  73.     
  74.     SetGWorld(theOffscreen->mMacGWorld, nil);
  75. //    SetOrigin(theOffscreen->mBounds.left, theOffscreen->mBounds.top);
  76.     LockPixels(GetGWorldPixMap(theOffscreen->mMacGWorld));
  77.     SetOrigin(theOffscreen->mBounds.left, theOffscreen->mBounds.top);
  78.     ForeColor (blackColor);
  79.     BackColor (whiteColor);
  80.     EraseRect(&theOffscreen->mBounds);
  81.     return theOffscreen;
  82. #else 
  83.     return nil;
  84. #endif
  85. }
  86.  
  87. WindowOffscreen *DrawOffscreenSaved(WindowOffscreen *inOffscreen, const Rect *inBounds, WindowPtr theWindow)
  88. {
  89. #if powerc
  90.     short inPixelDepth = 0;
  91.     GWorldFlags inFlags = useTempMem;
  92.     CTabHandle inCTableH = nil;
  93.     GDHandle inGDeviceH = nil;
  94.     WindowOffscreen    *theOffscreen;
  95.     Rect    bRect = (inBounds ? *inBounds : theWindow->portRect);
  96.     Rect    gwRect =  bRect;
  97.     
  98.     QDErr    err= noErr;
  99.     
  100.     if(inOffscreen) {
  101.         if(inBounds) {
  102.             if(!__EqualRect(inOffscreen->mMacGWorld->portRect, *inBounds)) {
  103.                 DisposeGWorld(inOffscreen->mMacGWorld);
  104.                 DisposePtr((Ptr)inOffscreen);
  105.                 inOffscreen = nil;
  106.             }
  107.         }
  108.         else {
  109.             if(!__EqualRect(inOffscreen->mMacGWorld->portRect, theWindow->portRect)) {
  110.                 DisposeGWorld(inOffscreen->mMacGWorld);
  111.                 DisposePtr((Ptr)inOffscreen);
  112.                 inOffscreen = nil;
  113.             }
  114.         }
  115.     }
  116.     
  117.     
  118.     
  119.     SetPort(theWindow);
  120.  
  121.     if(!inOffscreen) {
  122.         if ((theOffscreen = (WindowOffscreen *) NewPtr(sizeof(WindowOffscreen))) == 0L)
  123.             return(0L);
  124.     }
  125.     else {
  126.         theOffscreen = inOffscreen;
  127.     }
  128.         // We need to save the current GWorld because the image from
  129.         // the offscreen GWorld will be copied into this GWorld
  130.         // in the Destructor.
  131.         
  132.     GetGWorld(&theOffscreen->mSavePort, &theOffscreen->mSaveDevice);
  133.     
  134.     theOffscreen->mBounds =  bRect;
  135.     if(!inOffscreen || inOffscreen->mMacGWorld == nil) {
  136.         theOffscreen->mMacGWorld = nil;
  137.     
  138.         // NewGWorld interprets the bounds in global coordinates
  139.         // when specifying a zero pixel depth. It uses the maximum
  140.         // depth of all screen devices intersected by the bounds.
  141.     
  142.         if (inPixelDepth == 0) {
  143.             LocalToGlobal(&topLeft(gwRect));
  144.             LocalToGlobal(&botRight(gwRect));
  145.         }
  146.     
  147.         err = NewGWorld(&theOffscreen->mMacGWorld, inPixelDepth, &gwRect,
  148.                                 inCTableH, inGDeviceH, inFlags);
  149.     }    
  150.     if(err || theOffscreen->mMacGWorld == nil) {
  151.         DisposePtr((Ptr)theOffscreen);
  152.         return(0L);    
  153.     }        
  154.  
  155.         // Make offscreen GWorld the current one and prepare it
  156.         // for drawing by setting the coordinate system, and locking
  157.         // and erasing the pixels.
  158.     
  159.     SetGWorld(theOffscreen->mMacGWorld, nil);
  160. //    SetOrigin(theOffscreen->mBounds.left, theOffscreen->mBounds.top);
  161.     LockPixels(GetGWorldPixMap(theOffscreen->mMacGWorld));
  162.     SetOrigin(theOffscreen->mBounds.left, theOffscreen->mBounds.top);
  163.     ForeColor (blackColor);
  164.     BackColor (whiteColor);
  165.     EraseRect(&theOffscreen->mBounds);
  166.     return theOffscreen;
  167. #else 
  168.     return nil;
  169. #endif
  170. }
  171.  
  172. WindowOffscreen *DrawOffscreenNoInitialize(const Rect *inBounds, WindowPtr theWindow)
  173. {
  174.     return DrawOffscreen(inBounds, theWindow);
  175. }
  176.  
  177. // ---------------------------------------------------------------------------
  178. //        • ~StOffscreenGWorld
  179. // ---------------------------------------------------------------------------
  180. //    Destructor
  181. //
  182. //    Restores the current Port to what it was before the StOffscreenGWorld
  183. //    was created and copies the offscreen image to that Port
  184.  
  185. void DrawOnscreen(WindowOffscreen *theOffscreen)
  186. {
  187. #if powerc
  188.         // Restore current GWorld to the one which was current
  189.         // when the Constructor was called
  190.     if(theOffscreen) {
  191.         SetGWorld(theOffscreen->mSavePort, theOffscreen->mSaveDevice);
  192.         
  193.             // Copy image from the offscreen GWorld to the current GWorld,
  194.             // then destroy the offscreen GWorld
  195.         
  196.         if (theOffscreen->mMacGWorld != nil) {
  197.  
  198.             ForeColor (blackColor);
  199.             BackColor (whiteColor);
  200.  
  201.             CopyBits(&((GrafPtr)theOffscreen->mMacGWorld)->portBits,
  202.                         &((GrafPtr)theOffscreen->mSavePort)->portBits,
  203.                         &theOffscreen->mBounds, &theOffscreen->mBounds, srcCopy, nil);
  204.             UnlockPixels(GetGWorldPixMap(theOffscreen->mMacGWorld));
  205.             DisposeGWorld(theOffscreen->mMacGWorld);
  206.         }
  207.         DisposePtr((Ptr)theOffscreen);
  208.     }
  209. #endif
  210.  
  211. }
  212.  
  213. void DrawOnscreenSave(WindowOffscreen *theOffscreen)
  214. {
  215. #if powerc
  216.         // Restore current GWorld to the one which was current
  217.         // when the Constructor was called
  218.     if(theOffscreen) {
  219.         SetGWorld(theOffscreen->mSavePort, theOffscreen->mSaveDevice);
  220.         
  221.             // Copy image from the offscreen GWorld to the current GWorld,
  222.             // then destroy the offscreen GWorld
  223.         
  224.         if (theOffscreen->mMacGWorld != nil) {
  225.  
  226.             ForeColor (blackColor);
  227.             BackColor (whiteColor);
  228.  
  229.             CopyBits(&((GrafPtr)theOffscreen->mMacGWorld)->portBits,
  230.                         &((GrafPtr)theOffscreen->mSavePort)->portBits,
  231.                         &theOffscreen->mBounds, &theOffscreen->mBounds, srcCopy, nil);
  232.             UnlockPixels(GetGWorldPixMap(theOffscreen->mMacGWorld));
  233. //            DisposeGWorld(theOffscreen->mMacGWorld);
  234.         }
  235. //        DisposePtr((Ptr)theOffscreen);
  236.     }
  237. #endif
  238. }
  239.  
  240. void DisposeOffscreen(WindowOffscreen *theOffscreen)
  241. {
  242.     if(theOffscreen) {
  243.         if(theOffscreen->mMacGWorld) {
  244.             DisposeGWorld(theOffscreen->mMacGWorld);
  245.         }
  246.         DisposePtr((Ptr)theOffscreen);
  247.     }
  248. }